import standBookList from '@/biz/standBookList/standBookList'

function infoTypes() {
  return [{
    type: 1,
    key: 'baseInfoVos',
    title: '基本信息'
  }, {
    type: 2,
    key: 'serviceInfoVos',
    title: '服务信息'
  }, {
    type: 3,
    key: 'buyDemandVos',
    title: '置业需求'
  }, {
    type: 4,
    key: 'customerInfoVos',
    title: '客户画像'
  }]
}

function dictInfoType(key) {
  let dict = {}
  infoTypes().forEach(item => {
    dict[item[key]] = item
  })
  return dict
}

function addAll(list = {}) {
  delete list.all
  let all = []
  infoTypes().forEach(item => {
    let arr = list[item.key] || []
    arr = arr.sort((a, b) => {
      let at = a.fieldType == 1 ? 1 : 2
      let bt = b.fieldType == 1 ? 1 : 2
      if (at == bt) {
        return a.serialNo - b.serialNo
      } else {
        return at - bt
      }
    }).map((i, idx) => {
      i._disabled = i.fieldType == 2 || i.fieldType == 1
      i._key = item.key
      i._canUp = i.fieldType != 1 && idx != 0 && arr[idx - 1].fieldType != 1
      i._canDown = i.fieldType != 1 && idx != arr.length - 1 && arr[idx + 1]
        .fieldType != 1
      i._idx = idx
      return i
    })
    list[item.key] = arr
    all = [...all, ...arr]
  })
  list = {
    ...list,
    all
  }
  return list
}

function validArray(obj, key) {
  if (!obj[key]) {
    obj[key] = []
  }
  return obj[key]
}

class Field {
  constructor(added, unAdded, keys, buildingId) {
    this.added = added
    this.unAdded = unAdded
    this.keys = keys
    this.buildingId = buildingId
    this.delOptionId = []
  }

  fix() {
    this.added = addAll(this.added)
    this.unAdded = addAll(this.unAdded)
    return this
  }

  isEdit() {
    return this.added.all.some(i => i._type == 'edit') || this.unAdded.all.some(i => i
      ._type == 'edit')
  }

  hasFieldValue(item) {
    let has = (i) => {
      return i.fieldValue == item.fieldValue && i.standingBookBuildingId != item
        .standingBookBuildingId
    }
    return this.added.all.some(has) || this.unAdded.all.some(has)
  }

  add(list) {
    let dict = dictInfoType('type')
    list.forEach(item => {
      let key = dict[item.infoType].key
      item._type = 'edit'
      item.validate = 1
      let addArr = validArray(this.added, key)
      item.serialNo = addArr.length > 0 ? addArr[addArr.length - 1].serialNo + 1 : 1
      addArr.push(item)
      let unAddArr = validArray(this.unAdded, key)
      let idx = unAddArr.findIndex(i => i.dbKey == item.dbKey)
      unAddArr.splice(idx, 1)
    })
    return this.fix()
  }

  remove(list) {
    let dict = dictInfoType('type')
    list.forEach(item => {
      let key = dict[item.infoType].key
      item.validate = 2
      item._type = 'edit'
      let addArr = validArray(this.added, key)
      let idx = addArr.findIndex(i => i.dbKey == item.dbKey)
      addArr.splice(idx, 1)
      let unAddArr = validArray(this.unAdded, key)
      unAddArr.push(item)
    })
    return this.fix()
  }

  up(item) {
    let key = item._key
    let index = item._idx
    let arr = this.added[key]
    arr.splice(index - 1, 1, ...arr.splice(index, 1, arr[index - 1]))
    let serialNo = arr[index - 1].serialNo
    arr[index - 1].serialNo = arr[index].serialNo
    arr[index].serialNo = serialNo
    arr[index - 1]._type = 'edit'
    arr[index]._type = 'edit'
    return this.fix()
  }

  down(item) {
    let key = item._key
    let index = item._idx
    console.log(key, index, item)
    let arr = this.added[key]
    arr.splice(index, 1, ...arr.splice(index + 1, 1, arr[index]))
    let serialNo = arr[index + 1].serialNo
    arr[index + 1].serialNo = arr[index].serialNo
    arr[index].serialNo = serialNo
    arr[index + 1]._type = 'edit'
    arr[index]._type = 'edit'
    return this.fix()
  }

  editItem(item) {
    console.log(item._key)
    let key = item._key
    let dict = dictInfoType('type')
    let newKey = dict[item.infoType].key
    let obj = item.validate == 1 ? this.added : this.unAdded
    item._type = 'edit'
    if (newKey == key) {
      let index = item._idx
      let arr = obj[key]
      arr[index] = item
    } else {
      let arr = obj[key]
      let idx = arr.findIndex(i => i.dbKey == item.dbKey)
      arr.splice(idx, 1)
      let newArr = obj[newKey]
      newArr.push(item)
    }
    return this.fix()
  }

  addItem(item) {
    let dict = dictInfoType('type')
    let key = dict[item.infoType].key
    let addArr = validArray(this.added, key)
    item.serialNo = addArr.length > 0 ? addArr[addArr.length - 1].serialNo + 1 : 1
    return standBookList.createField({ ...item, buildingId: this.buildingId }).then(res => {
      addArr.push(res)
      this.fix()
      return res
    })
  }

  deleteOption(id) {
    if (id) {
      this.delOptionId.push(id)
    }
  }

  deleteItem(item) {
    return standBookList.delField({
      fieldId: item.standingBookBuildingId,
      buildingId: this.buildingId,
    }).then(res => {
      let dict = dictInfoType('type')
      let key = dict[item.infoType].key
      let unAddArr = validArray(this.unAdded, key)
      let idx = unAddArr.findIndex(i => i.dbKey == item.dbKey)
      unAddArr.splice(idx, 1)
      this.fix()
      return res
    })
  }

  save() {
    let fieldLibList = [...this.added.all.filter(item => item._type == 'edit'), ...this
      .unAdded.all.filter(item =>
        item._type == 'edit')
    ]
    return standBookList.fieldBatchUpdate({
      fieldLibList,
      buildingId: this.buildingId,
      delOptionId: this.delOptionId
    })
  }

}

function handleFields(list) {
  let added = {}
  let unAdded = {}
  let dict = dictInfoType('type')
  list.forEach(item => {
    let key = dict[item.infoType].key
    if (item.validate == 1) {
      let arr = added[key] || []
      arr.push(item)
      added[key] = arr
    } else {
      item._unAdd = true // 原来未被添加过的
      let arr = unAdded[key] || []
      arr.push(item)
      unAdded[key] = arr
    }
  })
  added = addAll(added)
  unAdded = addAll(unAdded)
  return {
    added,
    unAdded
  }
}

function infos(buildingId) {
  return standBookList.fieldLib({
    buildingId
  }).then(res => {
    let keys = [{
      type: 0,
      key: 'all',
      title: '全部'
    }, ...infoTypes()]
    let {
      added,
      unAdded
    } = handleFields(res)
    return new Field(added, unAdded, keys, buildingId)
  })
}

export default {
  infoTypes,
  infos
}